package com.ygqh.baby.service.impl;

import com.wdt.api.WdtResponse;
import com.wdt.api.exception.WdtException;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.kids.entity.bo.KidsProductExt;
import com.ygqh.baby.mapper.AdminSkuMapper;
import com.ygqh.baby.mapper.YgGroupMapper;
import com.ygqh.baby.mapper.YgSkuMaterialMapper;
import com.ygqh.baby.model.AdminSkuSearchReq;
import com.ygqh.baby.model.AdminSkuSearchVo;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.AdminSkuService;
import com.ygqh.baby.service.WdtQybGoodsService;
import com.ygqh.baby.service.YgGroupService;
import com.ygqh.baby.service.YgSkuMaterialService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class AdminSkuServiceImpl implements AdminSkuService {

    @Autowired
    private AdminSkuMapper adminSkuMapper;
    @Autowired
    private YgGroupMapper ygGroupMapper;
    @Autowired
    private YgGroupService ygGroupService;
    @Autowired
    private YgSkuMaterialMapper ygSkuMaterialMapper;
    @Autowired
    private YgSkuMaterialService ygSkuMaterialService;
    @Autowired
    private WdtQybGoodsService wdtQybGoodsService;

    @Override
    public List<AdminSku> find() {
        AdminSkuExample example = new AdminSkuExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return adminSkuMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        AdminSkuExample example = new AdminSkuExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return adminSkuMapper.countByExample(example);
    }

    @Override
    public AdminSku findById(Long id) {
        return adminSkuMapper.selectByPrimaryKey(id);
    }

    @Override
    public int save(AdminSku adminSku) {

        return adminSkuMapper.insertSelective(adminSku);
    }

    @Override
    public int update(AdminSku adminSku) {
        return adminSkuMapper.updateByPrimaryKeySelective(adminSku);
    }

    @Override
    public ResultSet<AdminSku> search(QueryInfo queryInfo, String q, Long groupId, String productCode) {
        List<AdminSku> list = adminSkuMapper.selectSuper(queryInfo, q, groupId, productCode);
        // 循环获取size
        Map<String, List<AdminSku>> collect = list.stream().collect(Collectors.groupingBy(o -> o.getProductCode()));

        List<AdminSku> newList = new ArrayList<AdminSku>();

        for (List<AdminSku> sku : collect.values()) {

            List<AdminSku> size = list.stream().filter(m -> m.getProductCode().equals(sku.get(0).getProductCode())).collect(Collectors.toList());
            List<String> sizelist = new ArrayList<String>();
            for (AdminSku s : size) {
                String str = "SKU编码:" + s.getSkuCode() + " 尺码:" + s.getSizeName();
                if (sizelist.indexOf(str) == -1)
                    sizelist.add(str);
            }
            sku.get(0).setSizeList(sizelist);
            newList.add(sku.get(0));
        }
        /*
         * Comparator<AdminSku> com=new Comparator<AdminSku>() {
         *
         * @Override public int compare(AdminSku o1, AdminSku o2) { // TODO
         * Auto-generated method stub if(o1.getId()>o2.getId()) return -1;
         * return 1; }
         *
         * };
         */
        /*
         * newList.sort((o1,o2)->{
         * if(o1.getCreateTime().compareTo(o2.getCreateTime())>0) return -1;
         * return 1;});
         */

        int count = adminSkuMapper.countSuper(q, groupId, productCode);
        ResultSet<AdminSku> resultSet = new ResultSet<AdminSku>(count, newList);
        return resultSet;
    }

    @Override
    public AdminSku findBySkuCode(String skuCode) {
        AdminSkuExample example = new AdminSkuExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andSkuCodeEqualTo(skuCode);
        List<AdminSku> skus = adminSkuMapper.selectByExample(example);
        if (!skus.isEmpty())
            return skus.get(0);

        return null;
    }

    @Override
    public int deleteSoft(Long[] ids) {
        Assert.notEmpty(ids);
        AdminSkuExample example = new AdminSkuExample();
        example.createCriteria().andIdIn(Arrays.asList(ids));
        AdminSku record = new AdminSku();
        record.setStatus(DataStatus.Delete);

        return adminSkuMapper.updateByExampleSelective(record, example);
    }

    @Override
    public int deleteSoft(Long id) {
        return this.deleteSoft(new Long[]{id});
    }

    @Override
    public int saveOrUpdate(AdminSku adminSku) {
        int r = 0;
        if (adminSku.getId() != null) {
            r = this.update(adminSku);
        } else {
            r = this.save(adminSku);
        }
        return r;
    }

    @Override
    public void saveBatch(List<AdminSku> adminSku, int groupCode, String userName, Long groupId) {
        String productCode = adminSku.get(0).getProductCode();
        List<YgSkuMaterial> skuMaterials = new ArrayList<YgSkuMaterial>();

        // 先删除当前productCode 下的所有Sku
        if (productCode.length() > 0) {
            AdminSkuExample example = new AdminSkuExample();
            example.createCriteria().andProductCodeEqualTo(productCode);
            List<AdminSku> oldList = adminSkuMapper.selectByExample(example);

            for (AdminSku sku : oldList) {
                for (AdminSku nsku : adminSku) {
                    if (nsku.getSizeName().equals(sku))
                        oldList.remove(sku);
                }
            }
            if (oldList.size() > 0)
                adminSkuMapper.updateBatch(oldList);
            int i = oldList.size();
            for (AdminSku sku : adminSku) {
                // 直接更新，返回值为0 则不存在
                int count = adminSkuMapper.updateStatusBySize(sku);
                if (count == 0) {
                    i++;
                    // 根据款式ID 获取最大的产品编码
                    // long
                    // maxCode=adminSkuMapper.selectMaxProductCode(adminSku.get(0).getGroupId());
                    // maxCode++;
                    sku.setSkuCode(productCode + i);
                    sku.setCreateBy(userName);
                    sku.setCreateTime(new Date());
                    this.save(sku);
                    // 组建SKU成本信息
                    YgSkuMaterial skuMaterial = new YgSkuMaterial();
                    skuMaterial.setProductCode(productCode);
                    skuMaterial.setSkuCode(productCode + i);
                    skuMaterial.setProductId(0L);
                    skuMaterial.setBarCode(productCode + i);
                    skuMaterial.setTagName(sku.getProductName());
                    skuMaterials.add(skuMaterial);
                }
            }

        } else {
            // 根据款式ID 获取最大的产品编码
            long maxCode = adminSkuMapper.selectMaxProductCode(adminSku.get(0).getGroupId());
            maxCode++;
            if (maxCode == 1) {
                productCode = groupCode + "0" + maxCode;
            } else {
                productCode = String.valueOf(maxCode);
            }
            // 循环明细 设置 skuCode和 productCode
            int i = 0;
            for (AdminSku sku : adminSku) {
                i++;
                sku.setProductCode(productCode);
                sku.setSkuCode(productCode + i);
                sku.setCreateTime(new Date());
                sku.setCreateBy(userName);
                // 组建SKU成本信息
                YgSkuMaterial skuMaterial = new YgSkuMaterial();
                skuMaterial.setProductCode(productCode);
                skuMaterial.setSkuCode(productCode + i);
                skuMaterial.setProductId(0L);
                skuMaterial.setBarCode(productCode + i);
                skuMaterial.setTagName(sku.getProductName());
                skuMaterials.add(skuMaterial);

            }

            adminSkuMapper.saveBatch(adminSku);
        }
        ygSkuMaterialService.saveSkuCostByGroupCode(skuMaterials, userName, groupId);
    }

    @Override
    public List<AdminSku> find(String productCode) {
        if (StringUtils.isBlank(productCode)) {
            return new ArrayList<>();
        }
        return adminSkuMapper.selectByProductCode(productCode);
    }

    @Override
    public int updateProduct(String productCode, String status) {
        return adminSkuMapper.updateByProductCode(productCode, status);
    }

    @Override
    public int updateSku(String skuCode, DataStatus status) {
        AdminSkuExample example = new AdminSkuExample();
        example.createCriteria().andSkuCodeEqualTo(skuCode);
        AdminSku record = new AdminSku();
        record.setStatus(status);
        return adminSkuMapper.updateByExampleSelective(record, example);
    }

    @Override
    public List<AdminSku> find(String q, Long groupId) {
        return adminSkuMapper.selectSuper(null, q, groupId, null);

    }

    @Override
    public ResultSet<AdminSku> searchByProduct(QueryInfo queryInfo, String productName, String productCode, String skuCode, Long groupId) {
        List<AdminSku> list = adminSkuMapper.selectSuperByProduct(queryInfo, productName, productCode, skuCode, groupId);

        // 循环获取size
        Map<String, List<AdminSku>> collect = list.stream().collect(Collectors.groupingBy(o -> o.getProductCode()));

        List<AdminSku> newList = new ArrayList<AdminSku>();

        for (List<AdminSku> sku : collect.values()) {

            List<AdminSku> size = list.stream().filter(m -> m.getProductCode().equals(sku.get(0).getProductCode())).collect(Collectors.toList());
            List<String> sizelist = new ArrayList<String>();
            for (AdminSku s : size) {
                String str = "SKU编码:" + s.getSkuCode() + " 尺码:" + s.getSizeName() + " 成本:" + s.getMaterial().getCostPrice();
                if (sizelist.indexOf(str) == -1)
                    sizelist.add(str);
            }
            sku.get(0).setSizeList(sizelist);
            newList.add(sku.get(0));
        }
        /*
         * newList.sort((o1,o2)->{
         * if(o1.getCreateTime().compareTo(o2.getCreateTime())>0) return -1;
         * return 1;});
         */

        int count = adminSkuMapper.countSuperByProduct(productName, productCode, skuCode, groupId);
        ResultSet<AdminSku> resultSet = new ResultSet<AdminSku>(count, newList);

        return resultSet;

    }

    @Override
    public List<AdminSku> selectSuperByProduct(QueryInfo queryInfo, String productName, String productCode, String skuCode, Long groupId) {
        return adminSkuMapper.selectSuperByProduct(queryInfo, productName, productCode, skuCode, groupId);
    }

    @Override
    public List<String> findBySkuCode(List<String> skuCode) {

        List<AdminSku> skus = adminSkuMapper.selectSkuCodeByLists(skuCode);
        if (skus == null)
            return null;
        for (AdminSku sku : skus) {
            if (skuCode.indexOf(sku.getSkuCode()) != -1)
                skuCode.remove(sku.getSkuCode());
        }
        return skuCode;
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    @Override
    public List<AdminSku> saveBatchSku(List<AdminSku> skuList, String createBy) {
        // 先判断款式名称是否存在，不存在则创建款式名称
        Map<String, YgGroup> groups = new HashMap<String, YgGroup>();
        List<AdminSku> colors = new ArrayList<AdminSku>();
        List<YgSkuMaterial> skuMaterials = new ArrayList<YgSkuMaterial>();
        // 循环获取款式名称,花色
        for (AdminSku sku : skuList) {
            if (!groups.containsKey(sku.getGroup().getGroupName())) {
                groups.put(sku.getGroup().getGroupName(), sku.getGroup());
            }
            boolean isexist = false;
            // 存在分组的情况下 ，判断 是否存在花色
            for (AdminSku s : colors) {
                if (s.getGroup().getGroupName().equals(sku.getGroup().getGroupName()) && s.getColor().equals(sku.getColor())) {
                    isexist = true;
                    break;
                }

            }
            if (!isexist)
                colors.add(sku);

        }

        // 循环获取款式名称是否存在。不存在 创建
        for (Entry<String, YgGroup> s : groups.entrySet()) {
            YgGroupExample example = new YgGroupExample();
            example.createCriteria().andGroupNameEqualTo(s.getKey()).andGroupTypeEqualTo(GroupType.Houtai.name()).andStatusEqualTo(DataStatus.Valid.name());

            List<YgGroup> list = ygGroupMapper.selectByExample(example);
            if (list.size() > 0) {
                s.setValue(list.get(0));
            } else {
                YgGroup newGroup = new YgGroup();
                newGroup.setSupplierId(1L);
                newGroup.setCreateBy(createBy);
                newGroup.setCreateTime(new Date());
                newGroup.setStatus(DataStatus.Valid);
                newGroup.setGroupType(GroupType.Houtai);
                newGroup.setGroupName(s.getKey());
                newGroup.setExtMaterial(s.getValue().getExtMaterial());
                newGroup.setCostPrice(s.getValue().getCostPrice());
                newGroup.setBasicAttribute(s.getValue().getBasicAttribute());
                newGroup.setCategoryId(s.getValue().getCategoryId());
                ygGroupService.save(newGroup);
                s.setValue(newGroup);

            }
        }
        // 循环花色，判断花色是否存在，不存在生成商品编码，存在 则获取最大尺码
        for (AdminSku s : colors) {
            String productCode = "";
            String groupName = s.getGroup().getGroupName();
            String colorName = s.getColor();
            Long groupCode = groups.get(groupName).getGroupCode();

            AdminSku skuCode = adminSkuMapper.selectProductCodeByGroupAndColor(groupName, colorName);

            // 获取所有当前款式 、颜色的尺码
            List<AdminSku> size = skuList.stream().filter(m -> m.getGroup().getGroupName().equals(groupName)).filter(m -> m.getColor().equals(colorName))
                    .collect(Collectors.toList());

            if (skuCode == null)// 不存在当前颜色
            {
                // 根据款式ID 获取最大的产品编码
                long maxCode = adminSkuMapper.selectMaxProductCode(groups.get(groupName).getId());
                maxCode++;
                if (maxCode == 1) {
                    productCode = groupCode + "0" + maxCode;
                } else {
                    productCode = String.valueOf(maxCode);
                }
                // 循环明细 设置 skuCode和 productCode
                int i = 0;
                for (AdminSku sku : size) {
                    i++;
                    sku.setGroupId(groups.get(groupName).getId());
                    sku.setProductCode(productCode);
                    sku.setSkuCode(productCode + i);
                    sku.setCreateTime(new Date());
                    sku.setCreateBy(createBy);
                    // 保存成本
                    setSkuMaterial(sku, createBy);

                }
                adminSkuMapper.saveBatch(size);

            } else {
                List<AdminSku> newList = new ArrayList<AdminSku>();
                // 保存sku
                int i = 0;
                for (AdminSku sku : size) {
                    i++;
                    // 取最后一位
                    String key = skuCode.getSkuCode().substring(8);
                    int n = Integer.valueOf(key) + i;

                    String code = skuCode.getSkuCode().substring(0, 8) + n;

                    sku.setGroupId(skuCode.getGroupId());
                    sku.setColor(skuCode.getColor());
                    sku.setProductCode(skuCode.getProductCode());
                    sku.setSkuCode(code);
                    sku.setCreateTime(new Date());
                    sku.setCreateBy(createBy);

                    newList.add(sku);
                    // 保存成本
                    setSkuMaterial(sku, createBy);
                }
                adminSkuMapper.saveBatch(newList);

            }

        }
        return skuList;

    }

    private void setSkuMaterial(AdminSku s, String createBy) {
        YgSkuMaterial sku = new YgSkuMaterial();
        sku.setProductCode(s.getProductCode());
        sku.setSkuCode(s.getSkuCode());
        sku.setBarCode(s.getSkuCode());
        sku.setCostPrice(s.getGroup().getCostPrice());
        sku.setExtMaterial(s.getGroup().getExtMaterial());
        sku.setCreateBy(createBy);
        sku.setCreateTime(new Date());
        sku.setStatus(DataStatus.Valid);
        sku.setProductId(0L);
        ygSkuMaterialMapper.insert(sku);

    }

    @Override
    public AdminSku selectSkuByName(String groupName, String productName, String color, String sizeName) {
        return adminSkuMapper.selectSkuByName(groupName, color, productName, sizeName);

    }

    @Override
    public int saveSkuBatch(List<AdminSku> adminSkuList, String updateBy) {
        if (CollectionUtils.isEmpty(adminSkuList)) {
            return 0;
        }
        //

        adminSkuMapper.saveBatch(adminSkuList);
        return 1;
    }

    @Override
    public List<String> findProductCodeByGroupId(Long groupId) {
        return adminSkuMapper.selectProductCodeByGroupId(groupId);
    }

    @Override
    public Long findMaxProductCode(Long groupId) {
        return adminSkuMapper.selectMaxProductCodeByGroupId(groupId);
    }

    @Override
    public AdminSku findOutCodeBySkuCode(String skuCode) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List<AdminSku> findListBySkuCode(List<String> skuCodeList) {
        Assert.notEmpty(skuCodeList, "SKU编码集不能为空");
        return adminSkuMapper.selectListBySkuCode(skuCodeList);
    }

    @Override
    public ResultSet<AdminSkuSearchVo> searchSku(AdminSkuSearchReq searchReq) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("productName", searchReq.getProductName());
        paramMap.put("productCode", searchReq.getProductCode());
        paramMap.put("skuCode", searchReq.getSkuCode());
        paramMap.put("groupId", searchReq.getGroupId());
        int total = adminSkuMapper.count(paramMap);
        if (total == 0) {
            return new ResultSet<>();
        }
        paramMap.put("start", searchReq.getStart());
        paramMap.put("end", searchReq.getEnd());
        List<AdminSkuSearchVo> result = adminSkuMapper.selectList(paramMap);
        return new ResultSet<>(total, result);
    }

    @Override
    public Message pushAdminSkuToWdtGoods(String productCode) {
        if (StringUtils.isBlank(productCode)) {
            return Message.error("param productCode can't be blank", null);
        }
        List<AdminSku> adminSkuList = this.findBaseInfoByProductCode(productCode);
        if (CollectionUtils.isEmpty(adminSkuList)) {
            return Message.error("select result data is empty", null);
        }
        try {
            WdtResponse response = wdtQybGoodsService.goodsPush(adminSkuList);
            if (response.getCode() != 0) {
                return Message.error(response.getMessage(), null);
            }
        } catch (WdtException e) {
            e.printStackTrace();
            return Message.error(e.getErrorMsg(), null);
        }
        updatePushWdtByProductCode(productCode, Boolean.TRUE);
        return Message.success(null);
    }

    @Override
    public List<KidsProductExt> findProductInfoForKids(String... productCode) {
        if (productCode == null || productCode.length == 0) {
            return new ArrayList<>();
        }
        return adminSkuMapper.selectProductInfoForKids(productCode);
    }

    @Override
    public List<KidsProductExt> findProductDataForKids(String[] skuCodes, String[] productCodes) {
        List<String> productCodeList;
        if (productCodes != null && productCodes.length > 0) {
            productCodeList = Arrays.asList(productCodes);
        } else {
            productCodeList = new ArrayList<>();
        }
        if (skuCodes != null && skuCodes.length > 0) {
            List<AdminSku> listBySkuCode = this.findListBySkuCode(Arrays.asList(skuCodes));
            if (CollectionUtils.isNotEmpty(listBySkuCode)) {
                productCodeList.addAll(listBySkuCode.stream().map(AdminSku::getProductCode).collect(Collectors.toSet()));
            }
        }
        if (productCodeList.size() == 0) {
            return Collections.emptyList();
        }
        return this.findProductInfoForKids(productCodeList.toArray(new String[0]));
    }

    private int updatePushWdtByProductCode(String productCode, Boolean pushWdt) {
        Assert.isTrue(StringUtils.isNotBlank(productCode), "param productCode can't be blank");
        Assert.notNull(pushWdt, "param pushWdt can't be null");
        return adminSkuMapper.updatePushWdtByProductCode(productCode, pushWdt);
    }

    private List<AdminSku> findBaseInfoByProductCode(String productCode) {
        if (StringUtils.isBlank(productCode)) {
            return null;
        }
        return adminSkuMapper.selectBaseInfoByProductCode(productCode);
    }


}
